"""
Flask 路由管理器工具类
专门用于管理插件的路由关系，维护插件名称与路由路径的映射
"""
import os
import json
from flask import Flask
import logging
import importlib.util
import sys
from typing import Dict, List, Optional, Set
from collections import defaultdict
import datetime

logger = logging.getLogger(__name__)


class RouteManager:
    """Flask 路由管理器工具类 - 只管理插件和路由的关系"""
    
    def __init__(self, app=None):
        """初始化路由管理器"""
        self.app = app
        self.plugin_dir = os.path.join(os.getcwd(), 'plugins') if app is None else os.path.join(app.root_path, '..', 'plugins')
        self.plugins_file = os.path.join(self.plugin_dir, 'plugins.json')
        
        # 插件路由关系映射
        self.plugin_routes = defaultdict(dict)  # {plugin_name: {'routes': set(), 'enabled': bool, 'info': dict, 'url_prefix': str, 'blueprint_name': str}}
        self.plugin_info = {}  # {plugin_name: plugin_config}
        
        # 确保插件目录存在
        os.makedirs(self.plugin_dir, exist_ok=True)
        
        # 加载已安装的插件信息
        self._load_plugins_info()
        
        # 从蓝图信息中提取路由关系
        self._extract_routes_from_blueprints()
        
        logger.info("✓ 路由管理器已初始化")
        # 遍历 self.plugin_routes
        for plugin_name, plugin_data in self.plugin_routes.items():
            logger.info(f"插件 {plugin_name} 的路由: {plugin_data.get('routes', set())}, 启用状态: {plugin_data.get('enabled', False)}, URL前缀: {plugin_data.get('url_prefix', '')}, 蓝图名称: {plugin_data.get('blueprint_name', '')}")
    
    def _load_plugins_info(self):
        """加载已安装的插件信息"""
        if os.path.exists(self.plugins_file):
            try:
                with open(self.plugins_file, 'r', encoding='utf-8') as f:
                    plugins = json.load(f)
                    for plugin_name, plugin_info in plugins.items():
                        self.plugin_info[plugin_name] = plugin_info
                        # 初始化插件路由集合
                        if plugin_name not in self.plugin_routes:
                            self.plugin_routes[plugin_name] = {'routes': set(), 'enabled': True, 'info': plugin_info}
            except Exception as e:
                logger.error(f"加载插件信息失败: {e}")
    
    def _extract_routes_from_blueprints(self):
        """从蓝图信息中提取路由关系"""
        if not os.path.exists(self.plugins_file):
            return
        
        try:
            with open(self.plugins_file, 'r', encoding='utf-8') as f:
                plugins = json.load(f)
            
            for plugin_name, plugin_info in plugins.items():
                logger.info(f"处理插件: {plugin_name}")
                
                # 检查是否有蓝图信息
                if 'blueprint_name' in plugin_info:
                    blueprint_name = plugin_info['blueprint_name']
                    url_prefix = plugin_info.get('url_prefix', '')
                    
                    logger.info(f"插件 {plugin_name} 的蓝图名称: {blueprint_name}")
                    logger.info(f"插件 {plugin_name} 的URL前缀: {url_prefix}")
                    
                    # 尝试从插件目录中获取路由信息
                    plugin_routes = self._get_plugin_routes_from_directory(plugin_name, blueprint_name, url_prefix)
                    
                    if plugin_routes:
                        # 注册从蓝图信息中提取的路由
                        enabled = plugin_info.get('enabled', True)  # 默认启用
                        self.register_plugin_routes(plugin_name, plugin_routes, plugin_info, enabled, url_prefix, blueprint_name)
                        logger.info(f"从蓝图信息中提取到 {plugin_name} 插件的 {len(plugin_routes)} 个路由，启用状态: {enabled}, URL前缀: {url_prefix}, 蓝图名称: {blueprint_name}")
                    else:
                        logger.warning(f"无法从蓝图信息中提取 {plugin_name} 插件的路由")
                        # 尝试不指定蓝图名称来解析路由
                        logger.info(f"尝试不指定蓝图名称解析 {plugin_name} 插件的路由")
                        plugin_routes = self._get_plugin_routes_from_directory(plugin_name, None, url_prefix)
                        if plugin_routes:
                            enabled = plugin_info.get('enabled', True)  # 默认启用
                            self.register_plugin_routes(plugin_name, plugin_routes, plugin_info, enabled, url_prefix, blueprint_name)
                            logger.info(f"不指定蓝图名称提取到 {plugin_name} 插件的 {len(plugin_routes)} 个路由，启用状态: {enabled}, URL前缀: {url_prefix}, 蓝图名称: {blueprint_name}")
                        else:
                            logger.warning(f"无法提取 {plugin_name} 插件的路由")
                        
        except Exception as e:
            logger.error(f"从蓝图信息中提取路由关系失败: {e}")
    
    def _get_plugin_routes_from_directory(self, plugin_name: str, blueprint_name: str, url_prefix: str) -> List[str]:
        """
        从插件目录中获取路由信息
        
        Args:
            plugin_name: 插件名称
            blueprint_name: 蓝图名称
            url_prefix: URL前缀
        
        Returns:
            List[str]: 路由列表
        """
        routes = []
        
        try:
            # 构建插件目录路径
            plugin_path = os.path.join(self.plugin_dir, plugin_name)
            if not os.path.exists(plugin_path):
                return routes
            
            # 查找可能的视图文件
            view_files = ['view.py', 'views.py', 'routes.py', '__init__.py']
            
            for view_file in view_files:
                view_path = os.path.join(plugin_path, view_file)
                if os.path.exists(view_path):
                    file_routes = self._extract_routes_from_module(view_path, blueprint_name, url_prefix)
                    routes.extend(file_routes)
                    break
            
            # 如果没有找到路由，记录警告信息
            if not routes:
                logger.warning(f"在插件 {plugin_name} 中未找到任何路由")
            
            return routes
            
        except Exception as e:
            logger.error(f"从插件目录获取路由失败 {plugin_name}: {e}")
            return routes
    
    def _extract_routes_from_module(self, file_path: str, blueprint_name: str, url_prefix: str) -> List[str]:
        """
        通过 importlib 加载模块并提取路由信息
        
        Args:
            file_path: 文件路径
            blueprint_name: 蓝图名称
            url_prefix: URL前缀
        
        Returns:
            List[str]: 路由列表
        """
        routes = []
        
        try:
            # 获取模块名称（去掉 .py 扩展名）
            module_name = os.path.splitext(os.path.basename(file_path))[0]
            plugin_dir = os.path.dirname(file_path)
            
            # 将插件目录添加到 Python 路径
            if plugin_dir not in sys.path:
                sys.path.insert(0, plugin_dir)
            
            # 首先尝试从源代码中解析路由（更可靠的方法）
            routes = self._parse_routes_from_file(file_path, url_prefix, blueprint_name)
            
            # 如果从源代码中解析到了路由，直接返回
            if routes:
                logger.info(f"从源代码中解析到 {len(routes)} 个路由")
                return routes
            
            # 如果从源代码中无法解析，尝试加载模块
            try:
                # 使用 importlib 加载模块
                spec = importlib.util.spec_from_file_location(module_name, file_path)
                if spec is None or spec.loader is None:
                    logger.warning(f"无法加载模块: {file_path}")
                    return routes
                
                module = importlib.util.module_from_spec(spec)
                # 设置模块的 __name__ 属性
                module.__name__ = module_name
                spec.loader.exec_module(module)
                
                # 查找蓝图对象
                blueprint_obj = None
                
                # 方法1: 直接查找蓝图名称对应的变量
                if hasattr(module, blueprint_name):
                    blueprint_obj = getattr(module, blueprint_name)
                
                # 方法2: 查找常见的蓝图变量名
                if blueprint_obj is None:
                    common_blueprint_names = ['bp', 'blueprint', 'app', 'main']
                    for name in common_blueprint_names:
                        if hasattr(module, name):
                            blueprint_obj = getattr(module, name)
                            break
                
                # 方法3: 查找所有 Blueprint 类型的对象
                if blueprint_obj is None:
                    from flask import Blueprint
                    for attr_name in dir(module):
                        attr_value = getattr(module, attr_name)
                        if isinstance(attr_value, Blueprint):
                            blueprint_obj = attr_value
                            break
                
                if blueprint_obj is None:
                    logger.warning(f"在模块 {file_path} 中未找到蓝图对象")
                    return routes
                
                # 从蓝图对象中提取路由
                routes = self._extract_routes_from_blueprint_obj(blueprint_obj, url_prefix)
                
                # 清理模块引用
                if hasattr(module, '__file__'):
                    del sys.modules[module.__name__]
                
            except Exception as e:
                logger.debug(f"模块加载失败，使用源代码解析: {e}")
                # 如果模块加载失败，再次尝试从源代码解析
                routes = self._parse_routes_from_file(file_path, url_prefix, blueprint_name)
            
            return routes
            
        except Exception as e:
            logger.error(f"从模块提取路由失败 {file_path}: {e}")
            return routes
    
    def _extract_routes_from_blueprint_obj(self, blueprint_obj, url_prefix: str) -> List[str]:
        """
        从蓝图对象中提取路由信息
        
        Args:
            blueprint_obj: Flask Blueprint 对象
            url_prefix: URL前缀
        
        Returns:
            List[str]: 路由列表
        """
        routes = []
        
        try:
            from flask import Blueprint
            
            if not isinstance(blueprint_obj, Blueprint):
                return routes
            
            # 首先尝试从视图函数中提取路由（蓝图可能还未注册到应用）
            routes = self._extract_routes_from_view_functions(blueprint_obj, url_prefix)
            
            # 如果从视图函数中提取到了路由，直接返回
            if routes:
                return routes
            
            # 如果蓝图已经注册到应用，尝试从 url_map 中获取路由规则
            try:
                if hasattr(blueprint_obj, 'url_map') and blueprint_obj.url_map:
                    for rule in blueprint_obj.url_map.iter_rules():
                        route_path = rule.rule
                        
                        # 构建完整路由路径
                        if route_path.startswith('/'):
                            full_route = url_prefix + route_path
                        else:
                            full_route = url_prefix + '/' + route_path
                        
                        routes.append(full_route)
            except Exception as e:
                logger.debug(f"从蓝图 url_map 提取路由失败: {e}")
            
            return routes
            
        except Exception as e:
            logger.error(f"从蓝图对象提取路由失败: {e}")
            return routes
    
    def _extract_routes_from_view_functions(self, blueprint_obj, url_prefix: str) -> List[str]:
        """
        从蓝图的视图函数中推断路由信息
        
        Args:
            blueprint_obj: Flask Blueprint 对象
            url_prefix: URL前缀
        
        Returns:
            List[str]: 路由列表
        """
        routes = []
        
        try:
            # 获取蓝图的视图函数
            view_functions = blueprint_obj.view_functions
            
            # 如果 view_functions 为空，返回空列表
            if not view_functions:
                logger.debug("蓝图对象的 view_functions 为空")
                return routes
            
            for endpoint, view_func in view_functions.items():
                # 尝试从视图函数的装饰器信息中获取路由路径
                route_path = self._get_route_from_view_function(view_func, endpoint)
                
                if route_path:
                    # 构建完整路由路径
                    if route_path.startswith('/'):
                        full_route = url_prefix + route_path
                    else:
                        full_route = url_prefix + '/' + route_path
                    
                    routes.append(full_route)
                else:
                    # 如果无法获取路由路径，根据端点名称推断
                    if endpoint == 'index':
                        route_path = '/'
                    else:
                        route_path = '/' + endpoint
                    
                    full_route = url_prefix + route_path
                    routes.append(full_route)
            
            return routes
            
        except Exception as e:
            logger.error(f"从视图函数提取路由失败: {e}")
            return routes
    

    
    def _parse_routes_from_file(self, file_path: str, url_prefix: str, blueprint_name: str = None) -> List[str]:
        """
        从文件中解析路由信息
        
        Args:
            file_path: 文件路径
            url_prefix: URL前缀
            blueprint_name: 蓝图名称（可选）
        
        Returns:
            List[str]: 路由列表
        """
        routes = []
        
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
            
            # 使用正则表达式解析路由装饰器
            import re
            
            # 匹配 @blueprint_name.route('path') 或 @blueprint_name.route("/path")
            # 支持多种蓝图变量名
            patterns = [
                r'@(\w+)\.route\([\'"]([^\'"]+)[\'"]',  # @bp.route('/path')
                r'@(\w+)\.route\([\'"]([^\'"]+)[\'"],?\s*methods\s*=\s*\[[^\]]*\]',  # @bp.route('/path', methods=['GET'])
                r'@(\w+)\.route\([\'"]([^\'"]+)[\'"],?\s*[^)]*\)',  # @bp.route('/path', other_params)
            ]
            
            logger.debug(f"解析文件: {file_path}")
            logger.debug(f"蓝图名称: {blueprint_name}")
            logger.debug(f"URL前缀: {url_prefix}")
            
            for pattern in patterns:
                matches = re.findall(pattern, content)
                for blueprint_var, route_path in matches:
                    logger.debug(f"找到路由: @{blueprint_var}.route('{route_path}')")
                    
                    # 如果指定了蓝图名称，只处理匹配的蓝图变量
                    if blueprint_name and blueprint_var != blueprint_name:
                        # 检查是否是常见的蓝图变量名
                        common_names = ['bp', 'blueprint', 'app', 'main']
                        if blueprint_var not in common_names:
                            logger.debug(f"跳过不匹配的蓝图变量: {blueprint_var} (期望: {blueprint_name})")
                            continue
                    
                    # 构建完整路由路径
                    if route_path.startswith('/'):
                        full_route = url_prefix + route_path
                    else:
                        full_route = url_prefix + '/' + route_path
                    
                    routes.append(full_route)
                    logger.debug(f"添加路由: {full_route}")
            
            # 去重并返回
            unique_routes = list(set(routes))
            logger.info(f"从文件 {file_path} 解析到 {len(unique_routes)} 个路由: {unique_routes}")
            return unique_routes
            
        except Exception as e:
            logger.debug(f"从文件解析路由失败 {file_path}: {e}")
            return routes
    
    def _get_route_from_view_function(self, view_func, endpoint: str) -> Optional[str]:
        """
        从视图函数中获取路由路径
        
        Args:
            view_func: 视图函数
            endpoint: 端点名称
        
        Returns:
            Optional[str]: 路由路径，如果无法获取则返回 None
        """
        try:
            # 检查视图函数是否有 __route__ 属性（Flask 内部使用）
            if hasattr(view_func, '__route__'):
                return view_func.__route__
            
            # 检查视图函数是否有 __name__ 属性
            if hasattr(view_func, '__name__'):
                func_name = view_func.__name__
                # 如果函数名与端点名不同，可能表示有自定义路由
                if func_name != endpoint:
                    # 尝试从函数名推断路由
                    if func_name == 'index':
                        return '/'
                    else:
                        return '/' + func_name
            
            # 检查视图函数的文档字符串中是否有路由信息
            if hasattr(view_func, '__doc__') and view_func.__doc__:
                doc = view_func.__doc__.strip()
                # 简单的路由提取逻辑
                import re
                route_match = re.search(r'@.*\.route\([\'"]([^\'"]+)[\'"]', doc)
                if route_match:
                    return route_match.group(1)
            
            return None
            
        except Exception as e:
            logger.debug(f"从视图函数获取路由失败: {e}")
            return None
    

    
    def register_plugin_routes(self, plugin_name: str, routes: List[str], 
                             plugin_config: Dict = None, enabled: bool = True,
                             url_prefix: str = '', blueprint_name: str = '') -> bool:
        """
        注册插件路由关系
        
        Args:
            plugin_name: 插件名称
            routes: 路由路径列表，如 ['/index', '/info', '/config']
            plugin_config: 插件配置信息（可选）
            enabled: 插件是否启用（默认True）
            url_prefix: URL前缀（可选）
            blueprint_name: 蓝图名称（可选）
        
        Returns:
            bool: 注册是否成功
        """
        try:
            if not routes:
                logger.warning(f"插件 {plugin_name} 没有提供路由信息")
                return False
            
            logger.info(f"注册插件路由关系: {plugin_name} -> {routes}, 启用状态: {enabled}, URL前缀: {url_prefix}, 蓝图名称: {blueprint_name}")
            
            # 更新插件信息
            if plugin_config:
                self.plugin_info[plugin_name] = plugin_config
            
            # 初始化插件数据结构
            if plugin_name not in self.plugin_routes:
                self.plugin_routes[plugin_name] = {
                    'routes': set(),
                    'enabled': enabled,
                    'info': plugin_config or {},
                    'url_prefix': url_prefix,
                    'blueprint_name': blueprint_name
                }
            else:
                # 更新启用状态和其他信息
                self.plugin_routes[plugin_name]['enabled'] = enabled
                if plugin_config:
                    self.plugin_routes[plugin_name]['info'] = plugin_config
                if url_prefix:
                    self.plugin_routes[plugin_name]['url_prefix'] = url_prefix
                if blueprint_name:
                    self.plugin_routes[plugin_name]['blueprint_name'] = blueprint_name
            
            # 注册路由关系
            for route in routes:
                # 确保路由以 / 开头
                if not route.startswith('/'):
                    route = '/' + route
                
                self.plugin_routes[plugin_name]['routes'].add(route)
            
            logger.info(f"✓ 插件 {plugin_name} 路由关系注册成功，共 {len(routes)} 个路由，启用状态: {enabled}")
            return True
            
        except Exception as e:
            logger.error(f"注册插件路由关系失败: {e}")
            return False
    
    def register_plugin_from_blueprint(self, plugin_name: str, blueprint_name: str, 
                                     url_prefix: str = '', plugin_config: Dict = None) -> bool:
        """
        从蓝图信息注册插件路由
        
        Args:
            plugin_name: 插件名称
            blueprint_name: 蓝图名称
            url_prefix: URL前缀
            plugin_config: 插件配置信息
        
        Returns:
            bool: 注册是否成功
        """
        try:
            # 从插件目录中获取路由
            routes = self._get_plugin_routes_from_directory(plugin_name, blueprint_name, url_prefix)
            
            if routes:
                return self.register_plugin_routes(plugin_name, routes, plugin_config)
            else:
                logger.warning(f"无法从蓝图信息中获取 {plugin_name} 插件的路由")
                return False
                
        except Exception as e:
            logger.error(f"从蓝图信息注册插件路由失败: {e}")
            return False
    
    def refresh_routes_from_blueprints(self) -> bool:
        """
        重新从蓝图信息中提取路由关系
        
        Returns:
            bool: 刷新是否成功
        """
        try:
            logger.info("开始从蓝图信息中刷新路由关系")
            
            # 清空当前路由关系
            self.plugin_routes.clear()
            
            # 重新加载插件信息
            self._load_plugins_info()
            
            # 重新提取路由关系
            self._extract_routes_from_blueprints()
            
            logger.info("✓ 从蓝图信息中刷新路由关系完成")
            return True
            
        except Exception as e:
            logger.error(f"从蓝图信息中刷新路由关系失败: {e}")
            return False
    
    def unregister_plugin_routes(self, plugin_name: str) -> bool:
        """
        注销插件路由关系
        
        Args:
            plugin_name: 插件名称
        
        Returns:
            bool: 注销是否成功
        """
        try:
            if plugin_name not in self.plugin_routes:
                logger.warning(f"插件 {plugin_name} 未找到路由信息")
                return False
            
            routes = self.plugin_routes[plugin_name]['routes']
            logger.info(f"注销插件路由关系: {plugin_name} -> {len(routes)} 个路由")
            
            # 清理插件路由集合
            del self.plugin_routes[plugin_name]
            
            # 清理插件信息
            if plugin_name in self.plugin_info:
                del self.plugin_info[plugin_name]
            
            logger.info(f"✓ 插件 {plugin_name} 路由关系注销成功")
            return True
            
        except Exception as e:
            logger.error(f"注销插件路由关系失败: {e}")
            return False
    
    def add_plugin_route(self, plugin_name: str, route: str) -> bool:
        """
        为插件添加单个路由
        
        Args:
            plugin_name: 插件名称
            route: 路由路径
        
        Returns:
            bool: 添加是否成功
        """
        try:
            # 确保路由以 / 开头
            if not route.startswith('/'):
                route = '/' + route
            
            self.plugin_routes[plugin_name]['routes'].add(route)
            
            logger.info(f"✓ 为插件 {plugin_name} 添加路由: {route}")
            return True
            
        except Exception as e:
            logger.error(f"添加插件路由失败: {e}")
            return False
    
    def remove_plugin_route(self, plugin_name: str, route: str) -> bool:
        """
        移除插件的单个路由
        
        Args:
            plugin_name: 插件名称
            route: 路由路径
        
        Returns:
            bool: 移除是否成功
        """
        try:
            # 确保路由以 / 开头
            if not route.startswith('/'):
                route = '/' + route
            
            if plugin_name in self.plugin_routes and route in self.plugin_routes[plugin_name]['routes']:
                self.plugin_routes[plugin_name]['routes'].remove(route)
                
                logger.info(f"✓ 移除插件 {plugin_name} 的路由: {route}")
                return True
            else:
                logger.warning(f"插件 {plugin_name} 的路由 {route} 不存在")
                return False
                
        except Exception as e:
            logger.error(f"移除插件路由失败: {e}")
            return False
    
    def get_plugin_routes(self, plugin_name: str = None) -> Dict:
        """
        获取插件路由信息
        
        Args:
            plugin_name: 插件名称，如果为 None 则返回所有插件
        
        Returns:
            Dict: 插件路由信息
        """
        if plugin_name:
            plugin_data = self.plugin_routes.get(plugin_name)
            if plugin_data:
                return {
                    plugin_name: {
                        'routes': list(plugin_data['routes']),
                        'route_count': len(plugin_data['routes']),
                        'enabled': plugin_data['enabled'],
                        'plugin_info': self.plugin_info.get(plugin_name, {}),
                        'url_prefix': plugin_data['url_prefix'], # 新增
                        'blueprint_name': plugin_data['blueprint_name'] # 新增
                    }
                }
            return {}
        else:
            result = {}
            for name, plugin_data in self.plugin_routes.items():
                result[name] = {
                    'routes': list(plugin_data['routes']),
                    'route_count': len(plugin_data['routes']),
                    'enabled': plugin_data['enabled'],
                    'plugin_info': self.plugin_info.get(name, {}),
                    'url_prefix': plugin_data['url_prefix'], # 新增
                    'blueprint_name': plugin_data['blueprint_name'] # 新增
                }
            return result
    
    def get_route_plugin(self, route: str) -> Optional[str]:
        """
        根据路由获取对应的插件名称
        
        Args:
            route: 路由路径
        
        Returns:
            Optional[str]: 插件名称，如果不存在则返回 None
        """
        # 确保路由以 / 开头
        if not route.startswith('/'):
            route = '/' + route
        
        for plugin_name, plugin_data in self.plugin_routes.items():
            if route in plugin_data['routes']:
                return plugin_name
        return None
    
    def is_plugin_route(self, route: str) -> bool:
        """
        判断是否是插件路由
        
        Args:
            route: 路由路径
        
        Returns:
            bool: 是否是插件路由
        """
        # 确保路由以 / 开头
        if not route.startswith('/'):
            route = '/' + route
        
        for plugin_name, plugin_data in self.plugin_routes.items():
            if route in plugin_data['routes']:
                return True
        return False

    def list_all_routes(self) -> List[Dict]:
        """
        列出所有路由信息
        
        Returns:
            List[Dict]: 路由信息列表
        """
        routes = []
        for plugin_name, plugin_data in self.plugin_routes.items():
            for route in plugin_data['routes']:
                routes.append({
                    'route': route,
                    'plugin_name': plugin_name,
                    'plugin_info': self.plugin_info.get(plugin_name, {}),
                    'enabled': plugin_data['enabled']
                })
        return routes
    
    def search_routes(self, keyword: str = None, plugin_name: str = None) -> List[Dict]:
        """
        搜索路由
        
        Args:
            keyword: 搜索关键词
            plugin_name: 插件名称过滤
        
        Returns:
            List[Dict]: 匹配的路由信息
        """
        results = []
        
        for name, plugin_data in self.plugin_routes.items():
            # 插件名称过滤
            if plugin_name and name != plugin_name:
                continue
            
            for route in plugin_data['routes']:
                # 关键词搜索
                if keyword:
                    keyword_lower = keyword.lower()
                    if (keyword_lower not in route.lower() and
                        keyword_lower not in name.lower()):
                        continue
                
                results.append({
                    'route': route,
                    'plugin_name': name,
                    'plugin_info': self.plugin_info.get(name, {}),
                    'enabled': plugin_data['enabled']
                })
        
        return results
    
    def get_route_statistics(self) -> Dict:
        """
        获取路由统计信息
        
        Returns:
            Dict: 统计信息
        """
        total_routes = sum(len(plugin_data['routes']) for plugin_data in self.plugin_routes.values())
        total_plugins = len(self.plugin_routes)
        
        # 按插件统计
        plugin_stats = {}
        for name, plugin_data in self.plugin_routes.items():
            plugin_stats[name] = {
                'route_count': len(plugin_data['routes']),
                'routes': list(plugin_data['routes']),
                'enabled': plugin_data['enabled'],
                'plugin_info': self.plugin_info.get(name, {}),
                'url_prefix': plugin_data['url_prefix'], # 新增
                'blueprint_name': plugin_data['blueprint_name'] # 新增
            }
        
        return {
            'total_routes': total_routes,
            'total_plugins': total_plugins,
            'plugin_statistics': plugin_stats,
            'registered_plugins': list(self.plugin_routes.keys())
        }
    
    def clear_all_routes(self) -> bool:
        """
        清空所有路由关系
        
        Returns:
            bool: 清空是否成功
        """
        try:
            self.plugin_routes.clear()
            self.plugin_info.clear()
            
            logger.info("✓ 所有路由关系已清空")
            return True
            
        except Exception as e:
            logger.error(f"清空路由关系失败: {e}")
            return False

    
    def enable_plugin(self, plugin_name: str) -> bool:
        """
        启用插件
        
        Args:
            plugin_name: 插件名称
        
        Returns:
            bool: 启用是否成功
        """
        try:
            if plugin_name in self.plugin_routes:
                self.plugin_routes[plugin_name]['enabled'] = True
                logger.info(f"✓ 插件 {plugin_name} 已启用")
                return True
            else:
                logger.warning(f"插件 {plugin_name} 不存在")
                return False
        except Exception as e:
            logger.error(f"启用插件失败: {e}")
            return False
    
    def disable_plugin(self, plugin_name: str) -> bool:
        """
        禁用插件
        
        Args:
            plugin_name: 插件名称
        
        Returns:
            bool: 禁用是否成功
        """
        try:
            if plugin_name in self.plugin_routes:
                self.plugin_routes[plugin_name]['enabled'] = False
                logger.info(f"✓ 插件 {plugin_name} 已禁用")
                return True
            else:
                logger.warning(f"插件 {plugin_name} 不存在")
                return False
        except Exception as e:
            logger.error(f"禁用插件失败: {e}")
            return False

    # 根据URL判断插件是否启用
    def is_route_enabled(self, route: str) -> bool:
        """
        根据URL判断插件是否启用

        Args:
            route: 路由路径

        Returns:
            bool: 路由是否启用
        """
        return self.is_plugin_enabled(self.get_route_plugin(route))
    def is_plugin_enabled(self, plugin_name: str) -> bool:
        """
        检查插件是否启用
        
        Args:
            plugin_name: 插件名称
        
        Returns:
            bool: 插件是否启用
        """
        if plugin_name in self.plugin_routes:
            return self.plugin_routes[plugin_name]['enabled']
        return False
    
    def get_enabled_plugins(self) -> List[str]:
        """
        获取所有启用的插件列表
        
        Returns:
            List[str]: 启用的插件名称列表
        """
        enabled_plugins = []
        for plugin_name, plugin_data in self.plugin_routes.items():
            if plugin_data['enabled']:
                enabled_plugins.append(plugin_name)
        return enabled_plugins
    
    def get_disabled_plugins(self) -> List[str]:
        """
        获取所有禁用的插件列表
        
        Returns:
            List[str]: 禁用的插件名称列表
        """
        disabled_plugins = []
        for plugin_name, plugin_data in self.plugin_routes.items():
            if not plugin_data['enabled']:
                disabled_plugins.append(plugin_name)
        return disabled_plugins
    
    def get_enabled_routes(self) -> List[str]:
        """
        获取所有启用插件的路由列表
        
        Returns:
            List[str]: 启用插件的路由列表
        """
        enabled_routes = []
        for plugin_name, plugin_data in self.plugin_routes.items():
            if plugin_data['enabled']:
                enabled_routes.extend(plugin_data['routes'])
        return enabled_routes
    
    def is_route_enabled(self, route: str) -> bool:
        """
        检查路由是否属于启用的插件
        
        Args:
            route: 路由路径
        
        Returns:
            bool: 路由是否启用
        """
        # 确保路由以 / 开头
        if not route.startswith('/'):
            route = '/' + route
        
        for plugin_name, plugin_data in self.plugin_routes.items():
            if route in plugin_data['routes']:
                return plugin_data['enabled']
        return False
# 全局路由管理器实例
_route_manager = None

def route_enable_plugin(plugin_name: str):
    get_route_manager().enable_plugin(plugin_name)

def route_disable_plugin(plugin_name: str):
    get_route_manager().disable_plugin(plugin_name)

def get_route_manager(app: Flask = None) -> RouteManager:
    """获取路由管理器实例"""
    global _route_manager

    if app is None:
        from flask import current_app
        app = current_app

    if _route_manager is None or _route_manager.app != app:
        _route_manager = RouteManager(app)

    return _route_manager